﻿using System;
using System.Collections.Generic;

namespace WindowsPhone.CompactContainer.ServiceLocation.CompactContainer
{
    /// <summary>
    /// Service locater implementation for the COmpact framework
    /// </summary>
    public class CompactServiceLocator : ServiceLocatorImplBase
    {
        private readonly IContainer _compactContainer;
        private bool _disposed;

        /// <summary>
        /// Initializes a new instance of the <see cref="CompactServiceLocator"/> class.
        /// </summary>
        /// <param name="compactContainer">The compact container.</param>
        public CompactServiceLocator(IContainer compactContainer)
        {
            _compactContainer = compactContainer;
        }

        #region Overrides of ServiceLocatorImplBase

        /// <summary>
        /// When implemented by inheriting classes, this method will do the actual work of resolving
        /// the requested service instance.
        /// </summary>
        /// <param name="serviceType">Type of instance requested.</param>
        /// <param name="key">Name of registered service you want. May be null.</param>
        /// <returns>The requested service instance.</returns>
        protected override object DoGetInstance(Type serviceType, string key)
        {
            object resolvedObject = null;

            // Resolve using a key if we have a key
            if (key !=null)
            {
                resolvedObject = _compactContainer.Resolve(key);
            }

            // Resolve using type if the object has not been resolved
            if(resolvedObject == null && serviceType != null)
            {
                resolvedObject = _compactContainer.Resolve(serviceType);
            }

            return resolvedObject;
        }

        /// <summary>
        /// When implemented by inheriting classes, this method will do the actual work of
        /// resolving all the requested service instances.
        /// </summary>
        /// <param name="serviceType">Type of service requested.</param>
        /// <returns>Sequence of service instance objects.</returns>
        protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
        {
            return _compactContainer.GetServices(serviceType);
        }

        /// <remarks />
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _compactContainer.Dispose();
                }
                _disposed = true;
            }
        }

        /// <remarks />
        public override void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
